#include "ThreadPool.h"
#include "Task.h"
#include <iostream>
using namespace std;

ThreadPool::ThreadPool(size_t threadNum, size_t queSize)
    : _threadNum(threadNum), _threads(), _queSize(queSize), _taskQue(_queSize), _isExit(false)
{
}

ThreadPool::~ThreadPool()
{
}

void ThreadPool::start()
{
    // 创建工作线程，并运行起来，同时还要存放在容器中
    for (size_t idx = 0; idx < _threadNum; idx++)
    {
        _threads.push_back(thread(&ThreadPool::doTask, this)); // 线程的拷贝构造已被删除，不能传递左值
    }
}
void ThreadPool::stop()
{
    // 任务执行完毕之后，才能继续向下执行
    while (!_taskQue.empty()) // 为了不让CPU空转，可以在此处睡觉
    {
        this_thread::sleep_for(chrono::seconds(1)); // 睡眠，释放CPU的控制权
    }

    _isExit = true; // 表示线程池要退出

    // 回收之前要先全部唤醒等待在_notEmpty()条件变量上的线程
    _taskQue.weakup();
    for (auto &th : _threads) // 回收子线程
    {
        th.join();
    }
}

void ThreadPool::addTask(Task *ptask)
{
    if (ptask)
    {
        _taskQue.push(ptask);
    }
}
Task *ThreadPool::getTask()
{
    return _taskQue.pop();
}

void ThreadPool::doTask() // 线程入口函数
{
    // 只要线程池不退出，就一直执行任务
    while (!_isExit || !_taskQue.empty())
    {
        Task *ptask = getTask();
        if (ptask)
        {
            ptask->process(); // 多态
            // this_thread::sleep_for(chrono::seconds(1));
        }
        else
        {
            cout << "ptask = nullptr : " << ptask << endl;
        }
    }
}